import Background from '../runtime/background'
import RouteSelect from '../runtime/routeSelect'
import DataBus from '../databus'
import * as utils from '../libs/utils'
import ControlLayer from "../base/controllayer";

const ctx = canvas.getContext('2d')
setGlobalCtx(ctx);
const databus = new DataBus()



import {PageStatus} from "../page_status";
import XmlManager from "../manager/xml_manager";
import GameIntroduce from "../runtime/gameintroduce";
import TripShow from "./runtime/tripshow";
import {globalCtx, setGlobalCtx} from "../libs/utils";
import MainMenu from "./runtime/mainMenu";
import Music from "./music/music";
import JsLogic, {LogicDebugMode} from "../runtime/jslogic";


const worker = wx.createWorker('workers/request/index.js')

worker.postMessage({
    msg: 'hello from AppService',
    buffer: utils.str2ab('hello arrayBuffer from AppService')
})

worker.onMessage(function (msg) {
    console.log('[AppService] onWorkerMessage', msg)
    const buffer = msg.buffer
    console.log('[AppService] on worker buffer', utils.ab2str(buffer))

})

console.log(`[AppService] on worker create: ${worker.onMessage}`)


/**
 * 游戏主函数
 */
export default class Game {
    constructor() {
        // 维护当前requestAnimationFrame的id

        this.aniId = 0

        wx.loadFont('js/sub/fonts/ZCOOL_KuaiLe_Stremline.ttf');

        ['touchstart', 'touchmove', 'touchend'].forEach((type) => {
            canvas.addEventListener(type, this.touchEventHandler.bind(this))
        });
        this.restart()
    }

    restart() {
        databus.reset()
        this.jsLogic = new JsLogic(LogicDebugMode)
        this.bg = new Background(ctx)

        this.gameIntroduce = new GameIntroduce()
        this.mainMenu = new MainMenu()
        this.routeSelect = new RouteSelect()
        this.tripShow = new TripShow()

        // debugger
        if(this.jsLogic.isNewUser){
            databus.gameStatus = PageStatus.GameIntroduce
            this.ctrlLayerUI = new ControlLayer('UI', [
                this.gameIntroduce, this.mainMenu, this.routeSelect, this.tripShow,this.jsLogic])
        }else{
            wx.getStorage({
                key:"lastPage",
                encrypt: false,
                success: res => {
                    console.log("xxxxx getInfo suc")
                   if(res.data === PageStatus.GameMainMenu){

                       databus.gameStatus = PageStatus.GameMainMenu
                   }else {
                       databus.gameStatus = PageStatus.TripShow
                   }
                    this.ctrlLayerUI = new ControlLayer('UI', [
                        this.mainMenu,  this.tripShow,this.jsLogic])
                },
                fail: () => {
                    console.log("xxxxx getInfo fail")
                    databus.gameStatus = PageStatus.GameMainMenu
                    this.ctrlLayerUI = new ControlLayer('UI', [
                        this.mainMenu,  this.tripShow,this.jsLogic])
                }
            })

        }

        // this.ctrlLayerUI = new ControlLayer('UI', [this.mainMenu])
        this.ctrlLayerBackground = new ControlLayer('Background', [this.bg])
        this.bindLoop = this.loop.bind(this)

        // 清除上一局的动画
        window.cancelAnimationFrame(this.aniId)

        this.aniId = window.requestAnimationFrame(
            this.bindLoop,
            canvas
        )

        this.music = new Music()
    }

    // 游戏结束后的触摸事件处理逻辑
    touchEventHandler(e) {
        e.preventDefault()

        let [x, y] = (e.type === 'touchstart' || e.type === 'touchmove') ?
            [e.touches[0].clientX, e.touches[0].clientY] : [null, null]


        //规则：1.只会从上层往下层传(只有捕获capture，没有冒泡bubble)
        //     2.当上层发生过处理时下层不再处理(parent-catch)
        //     3.同一层中，有一个元素处理过（队头优先）其他元素即不再处理(sibling-catch)
        let upperLayerHandled = false
        for (let ctrlLayer of [this.ctrlLayerBackground, this.ctrlLayerUI]) {
            if (upperLayerHandled)
                break //stop handling
            if (!ctrlLayer.active)
                continue //next layer
            // console.log(`${e.type}: ${ctrlLayer.name}`)
            ctrlLayer.elements.some((element) => {
                //console.log(`${e.type}: ${element.__proto__.constructor.name}`)
                element.onTouchEvent(e.type, x, y, ((res) => {

                    switch (res.message) {
                        //--- Game Status Switch ---
                        case 'showCard':
                            /// 显示猫咪发来的卡片
                            this.showCard()
                            break
                        case 'restart':
                            this.restart()
                            break
                        case 'pause':
                            this.pause()
                            break
                        case 'resume':
                            this.resume()
                            break
                        case 'playChess':
                            /// 点击跳棋
                            this.playChess()
                    }
                    if (res.message.length > 0) {
                        upperLayerHandled = true
                        return true // 已经有元素处理了点击事件，停止循环
                    }
                }).bind(this))
                if (upperLayerHandled) {
                    // 已经有元素处理了点击事件，停止循环
                    return true
                }
            })
        }

    }

    /**
     * canvas重绘函数
     * 每一帧重新绘制所有的需要展示的元素
     */
    render() {
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        this.bg.render(ctx)
        this.ctrlLayerUI.elements.some((element) => {
            element.render(ctx)
        })

    }

    // 游戏逻辑更新主函数
    update() {

        this.jsLogic.update(databus.frame)


        if (databus.gameOver) return
        this.bg.update()

        this.ctrlLayerUI.elements.some((element) => {
            element.update(ctx)
        })

        if (databus.gameStatus !== PageStatus.GameStart) return;
    }

    // 实现游戏帧循环
    loop() {
        databus.frame++
        this.update()
        this.render()
        this.aniId = window.requestAnimationFrame(
            this.bindLoop,
            canvas
        )
    }
}
new Game()